<?php

namespace App\Job\Console\Commands\Order;

use App\Models\ItemOrderPayment;
use App\Models\OrderCommission;
use App\Repositories\Money\BalanceRepositoryInterface;
use App\Repositories\Money\MoneyRepositoryInterface;
use Carbon\Carbon;
use Illuminate\Console\Command;
use DB;

class OrderPaymentAndCommission extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'order:payment:commission';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '订单完成后给卖家回款，及相关佣金分成';

    /**
     * @var MoneyRepositoryInterface
     */
    private $money_repository;
    /**
     * @var BalanceRepositoryInterface
     */
    private $balance_repository;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();

        $this->money_repository = app(MoneyRepositoryInterface::class);
        $this->balance_repository = app(BalanceRepositoryInterface::class);
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->info('====开始时间：' . date('Y-m-d H:i:s') . ' ' . __CLASS__);
        ItemOrderPayment::query()
            ->where('status', ItemOrderPayment::STATUS_PENDING)
            ->where('date', '<=', Carbon::now()->toDateTimeString())
            ->chunkById(5, function ($payments) {
                foreach ($payments as $payment) {
                    $this->info('待回款订单信息');
                    $this->info(print_r($payment->toArray(), true));

                    DB::beginTransaction();
                    try {
                        //处理订单回款
                        $this->handleOrderPayment($payment);

                        //处理订单佣金分成
                        $this->handleOrderCommission($payment->order_id);

                        //完成回款
                        $this->completePayment($payment->id, ItemOrderPayment::STATUS_SUCCESS);
                        DB::commit();
                        $this->info('订单回款处理成功');
                    } catch (\Exception $e) {
                        DB::rollBack();

                        $this->completePayment($payment->id, ItemOrderPayment::STATUS_FAILURE);
                        $this->info('订单回款处理失败，失败原因：' . $e->getMessage());
                    }
                }
                $this->info("\n\n");
            });

        $this->info('==结束==');
    }

    /**
     * 处理订单回款
     *
     * @param $payment
     */
    private function handleOrderPayment($payment)
    {
        //======卖家
        //信息订单获取回款
        $flow = $this->money_repository->storeFromPublish(
            $payment->publisher_uid,
            $payment->order_id,
            $payment->publisher_money,
            '发布信息订单回款'
        );

        //余额明细
        $this->balance_repository->store(
            $payment->publisher_uid,
            $flow->id,
            $payment->publisher_money,
            '发布信息订单回款'
        );

        //======平台
        //订单佣金回款
        $flow = $this->money_repository->storePlatformPublishCommission(
            $payment->order_id,
            $payment->platform_money
        );

        //余额明细
        $this->balance_repository->storePlatform(
            $flow->id,
            $payment->platform_money
        );
    }

    /**
     * 处理订单佣金分成
     *
     * @param $payment
     */
    private function handleOrderCommission($order_id)
    {
        $commissions = $this->getPendingOrderCommission($order_id);

        $this->info('订单佣金分成');
        foreach ($commissions as $commission) {
            $this->info('订单佣金分成信息');
            $this->info(print_r($commission->toArray(), true));
            try {
                $this->userOrderCommission($commission);
                $this->completeCommission($commission->id, OrderCommission::STATUS_SUCCESS);

                $this->info('佣金分成处理完成');
            } catch (\Exception $e) {
                $this->completeCommission($commission->id, OrderCommission::STATUS_FAILURE);

                $this->info('佣金分成处理失败，失败原因' . $e->getMessage());
            }
            $this->info("\n\n");
        }
    }

    /**
     * 发放用户订单佣金分成
     *
     * @param $commission
     */
    private function userOrderCommission($commission)
    {
        $flow = $platform_flow = null;
        $user_id = $commission->user_id;
        $order_id = $commission->order_id;
        $money = $commission->money;
        //======卖家
        //邀请佣金
        if ($commission->isUserInvite()) {
            $flow = $this->money_repository->storeInviteUser($user_id, $order_id, $money);
        } elseif ($commission->isPublisherInvite()) {
            $flow = $this->money_repository->storeInvitePublisher($user_id, $order_id, $money);
        }

        //余额明细
        $this->balance_repository->store($user_id, $flow->id, $money);

        //======平台
        //平台付出佣金
        $platform_money = -$money;
        if ($commission->isUserInvite()) {
            $platform_flow = $this->money_repository->storePlatformInviteUserCommission($user_id, $platform_money);
        } elseif ($commission->isPublisherInvite()) {
            $platform_flow = $this->money_repository->storePlatformInvitePublisherCommission(
                $order_id,
                $platform_money
            );
        }

        //平台余额明细
        $this->balance_repository->storePlatform($platform_flow->id, $platform_money);
    }

    /**
     * 待处理的佣金分成
     *
     * @param $order_id
     *
     * @return OrderCommission[]
     */
    private function getPendingOrderCommission($order_id)
    {
        return OrderCommission::query()
            ->where('order_id', $order_id)
            ->where('status', OrderCommission::STATUS_PENDING)
            ->get();
    }

    /**
     * 完成卖家回款
     *
     * @param     $payment_id
     * @param int $status
     *
     * @return bool
     */
    private function completePayment($payment_id, $status = ItemOrderPayment::STATUS_SUCCESS)
    {
        $payment = ItemOrderPayment::query()->find((int)$payment_id);
        if (!$payment) {
            return false;
        }

        $payment->status = $status;

        return $payment->save();
    }

    /**
     * 完成用户订单佣金发放
     *
     * @param     $commission_id
     * @param int $status
     *
     * @return bool
     */
    private function completeCommission($commission_id, $status = OrderCommission::STATUS_SUCCESS)
    {
        $commission = OrderCommission::query()->find($commission_id);
        if (!$commission) {
            return false;
        }

        $commission->status = $status;

        return $commission->save();
    }
}
